package com.banmao.snake_core.util;

import com.banmao.snake_core.myinterface.FXMLView;
import com.banmao.snake_core.myinterface.TransDataMethod;
import javafx.fxml.FXMLLoader;
import javafx.scene.Node;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.net.URL;

@Slf4j
public class FXMLUtil {

    public static Node loadFxml(String fxmlPath, TransDataMethod transDataMethod, Object data) throws IOException {
        URL url = FXMLUtil.class.getResource(fxmlPath);
        if(url != null) {
            FXMLLoader fxmlLoader = new FXMLLoader(url);

            Node node = fxmlLoader.load();

            if (transDataMethod != null) {
                Object controller = fxmlLoader.getController();
                transDataMethod.transData(controller, data);
            }
            return node;
        }
        return null;
    }

    public static Node getNodeByFxml(TabPane tabPane, Class<?> viewClass) throws Exception {
        Node node = getNode(AnnotationUtil.getValue(viewClass, FXMLView.class), null, null);

        return node;
    }

    public static Node getNodeByFxml(TabPane tabPane, String fxmlPath) throws Exception {
        Node node = getNode(fxmlPath, null, null);

        return node;
    }

    private static Node getNode(String viewClass, TransDataMethod transDataMethod, Object data) throws IOException {
        String value = viewClass;
        if(StringUtils.isBlank(value)) {
            throw new RuntimeException("无法加载资源，没有对应的FXMLView注解");
        }

        Node node = FXMLUtil.loadFxml(value, transDataMethod, data);
        if(node == null) {
            throw new RuntimeException("无法解析资源");
        }
        return node;
    }

    private static final String UNNAME_TAB = "未命名";
    private static final String TAB_SEPARATOR = " ";

    // 向tabPane中加载tab
    public static Tab loadFxmlToTabPane(TabPane tabPane, Class<?> viewClass) throws Exception {
        int tabSize = tabPane.getTabs().size();
        if (tabSize >= 30) {
            log.error("tab栏已达到上限: {}", tabSize);
            ToastUtil.toast("tab栏已达到上限: " + tabSize);
            return null;
        }

        Node node = getNode(AnnotationUtil.getValue(viewClass, FXMLView.class), null, null);

        return getTab(tabPane, viewClass, node);
    }

    public static Tab loadFxmlToTabPane(TabPane tabPane, Class<?> viewClass, Object data, TransDataMethod transMethod) throws Exception {
        int tabSize = tabPane.getTabs().size();
        if (tabSize >= 30) {
            log.error("tab栏已达到上限: {}", tabSize);
            ToastUtil.toast("tab栏已达到上限: " + tabSize);
            return null;
        }

        Node node = getNode(AnnotationUtil.getValue(viewClass, FXMLView.class), transMethod, data);

        return getTab(tabPane, viewClass, node);
    }

    private static Tab getTab(TabPane tabPane, Class<?> viewClass, Node node) {
        String title = (String) AnnotationUtil.getProperty(viewClass, FXMLView.class, "title");

        Integer maxTabNum = (Integer) AnnotationUtil.getProperty(viewClass, FXMLView.class, "maxTabNum");

        if (StringUtils.isBlank(title)) {
            // 该tab未命名，进行默认赋值
            int max = getMaxNum(tabPane, UNNAME_TAB);
            if (maxTabNum != null && max >= maxTabNum + 1) {
                return null;
            }
            title = max == 1 ? UNNAME_TAB : UNNAME_TAB + TAB_SEPARATOR + max;
        } else {
            int max = getMaxNum(tabPane, title);
            if (maxTabNum != null && max >= maxTabNum + 1) {
                return null;
            }
            title = max == 1 ? title : title + TAB_SEPARATOR + max;
        }

        Tab tab = new Tab(title, node);
        tab.setClosable(true);
        tabPane.getTabs().add(tab);
        return tab;
    }

    private static int getMaxNum(TabPane tabPane, String tabName) {
        int max = 1;
        for (Tab tab : tabPane.getTabs()) {
            String text = tab.getText();
            for (String name : text.split(TAB_SEPARATOR)) {
                if(name.equalsIgnoreCase(tabName)) {
                    max++;
                }
            }
        }
        return max;
    }

}
